
package ev.operator;

import ev.data.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

import org.omg.CORBA.PUBLIC_MEMBER;


public class MPX implements Crossover {
	

	
	private int subtourLength;		
	private boolean hasCrossedOverAgain;
		
	
	public MPX(){
	
    	hasCrossedOverAgain = false;
       
	}
	
	
	
	
	public	ArrayList<Individual> cross(Individual a, Individual b) {
		 
	
		
		int[] aArray = a.getList();
		Random random = new Random();
		int alength = aArray.length;
		subtourLength = random.nextInt(alength/4+1) + alength/4;
	  
	    HashMap<Integer,Integer> childChromosomes  = new HashMap<Integer,Integer>((int)(alength * 1.25), (float)1.0);
	     
		 //Individual child = new Individual(new int[alength]);
		 
		 int [] childArray = new int[alength]; 

		 int nextCity;
		 
		 // here, later we also nees to get the random value about cut
		 int  cut = (int)Math.rint(Math.random()*(alength-1));
		 
		 
		 
		 // which part we will keep in the next generation from parents
		for (int i=cut; i<cut+subtourLength; i++) {
		    nextCity = aArray[i];
			childArray[i]=nextCity;
			childChromosomes.put(nextCity, i);
					
			}

			
			
			//crossover for the left part of parent
			int value = 0;
			boolean  symbol = false;
			for (int i=0; i<cut; i++) {
		
				int[] x = b.getList();
				nextCity = x[i];
				
				if(symbol)
				nextCity = value;
				
			  
			    if (!childChromosomes.containsKey
				(nextCity)) {
						
			    
					
					childArray[i]    =   nextCity;
					 childChromosomes.put(nextCity, i);
					 symbol = false;
						
			    }
			    else{
			    	i = i-1;
			    	int yy = 0 ;
			    	
			    	for(int k = 0;k<a.getList().length;k++)
			    	{
			    		int[] zkkk = a.getList();
			    		if(zkkk[k]==nextCity)
			    			yy = k;
			    		
			    	}
			    
			    	
			    	int[] zkn = b.getList();
			    	symbol = true;
			    	value = zkn[yy]; 
			    	
			    }
					
			}
			
//			crossover for the right part of parent
			value = 0;
			 symbol = false;
			
			for (int i=cut+subtourLength; i<alength; i++) {
				
				int[] x = b.getList();
				nextCity = x[i];
				
				
				if(symbol)
				{
					nextCity = value;
				}
			   
			    if (!childChromosomes.containsKey
				(nextCity)) {
						
			   
		
					
					childArray[i]    =   nextCity;
					 childChromosomes.put(nextCity, i);
					 
					 
						
			    }
			    else{
			    	i = i-1;
			    	int yy = 0 ;
			    	
			    	for(int k = 0;k<a.getList().length;k++)
			    	{
			    		int[] zkkk = a.getList();
			    		if(zkkk[k]==nextCity)
			    			yy = k;
			    		
			    	}
			    	
			    	
			    	int[] zkn = b.getList();
			    	symbol = true;
			    	value = zkn[yy]; 
			    	
			    				    	
			    }
					
			}
			
			
			// now we just get only one kid based on parent a,  we need get other kid based on  parent b
			ArrayList<Individual> children;
			if (!hasCrossedOverAgain) {
			    hasCrossedOverAgain = true;
			    children = cross(b, a);
			    hasCrossedOverAgain = false;
			} else {
			    children = new ArrayList<Individual>();
			}
			
		
			Individual child = new Individual(childArray);
			children.add(child);
				
			return children;		
		 
	 }

}

